package com.zretc.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zretc.dao.OrdersDetailMapper;
import com.zretc.dao.OrdersMapper;
import com.zretc.dao.RefundMapper;
import com.zretc.dao.ScreeningMapper;
import com.zretc.entity.*;
import com.zretc.service.FrontOrdersService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Service
public class FrontOrdersServiceImpl implements FrontOrdersService {
    @Autowired
    private OrdersDetailMapper ordersDetailMapper;
    @Autowired
    private ScreeningMapper screeningMapper;
    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private RefundMapper refundMapper;
    // 设置座位行
    private static final int SEAT_LINE = 10;
    // 设置座位列
    private static final int SEAT_COLUMN = 10;
    private static final Logger LOGGER = LoggerFactory.getLogger(FrontOrdersServiceImpl.class);
    @Override
    public List<Screening> getScreening(Integer filmId) {
        //查找该电影全部场次（现在时间之后的）
        // 封装条件
        Map<String,String> condition = new HashMap<>();
        condition.put("filmId",filmId+"");
        // 获取现在时间
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String newDate = formatter.format(now);
        condition.put("startTime",newDate);
        List<Screening> list = screeningMapper.getScreeningList(condition);
        return list;
    }

    @Override
    public Integer[][] getSeat(String screeningId) {
        // 初始化二维数组
        Integer[][] seatArray = new Integer[SEAT_LINE][SEAT_COLUMN];
        for(int i = 0; i < seatArray.length; i++){
            for(int j = 0; j <seatArray[i].length; j++){
                seatArray[i][j] = 0;
            }
        }

        // 查找这个场次的所有已做的位置（从redis）10x10座位表
        // 根据场次查找所有订单详情位置
        List<OrdersDetail> list = ordersDetailMapper.getSeatByScreening(Integer.valueOf(screeningId));
        // 遍历座位进订单数组
        for (OrdersDetail ordersDetail : list) {
            // 计算位置
            int line = ordersDetail.getSeatLine();
            int column = ordersDetail.getSeatColumn();
            seatArray[line-1][column-1] = 1;
        }
        // 返回数组
        return seatArray;
    }

    @Override
    public Vip getVipByAccountId(Integer accountId) {
        return null;
    }

    @Override
    @Transactional
    public boolean createOrders(Map<String, Object> map) {
        // 获取场次编号
        Integer screeningId = Integer.valueOf((String)map.get("screeningId"));
        // 获取座位
        String[] seatArray = (String[]) map.get("seatArray");
        synchronized (this){ // 线程锁住代码块防止出现位置相同
            try{
                // 判断位置是否有相同
                List<OrdersDetail> list = ordersDetailMapper.getSeatByScreening(screeningId);
                // 遍历座位进订单数组
                for (OrdersDetail ordersDetail : list) {
                    // 计算位置
                    int line = ordersDetail.getSeatLine();
                    int column = ordersDetail.getSeatColumn();
                    Integer seat = (line-1)*SEAT_COLUMN+(column-1);
                    for (String s : seatArray) {
                        Integer IntSeat = Integer.valueOf(s);
                        if(IntSeat.equals(seat)){
                            throw new RuntimeException("座位已存在，订单无效，已回滚");
                        }
                    }

                }
                // 订单号生成
                StringBuilder orderId = new StringBuilder("");
                // 获取现在时间
                LocalDateTime now = LocalDateTime.now();
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
                String newDate = formatter.format(now);
                orderId.append(newDate);
                // 获取个随机数
                Random random = new Random();
                orderId.append((random.nextInt(89999)+10000));
                // 获取用户编号
                Integer accountId = Integer.valueOf((String)map.get("accountId"));
                // 获取现在时间
                formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                newDate = formatter.format(now);
                // 获取支付方式
                String payType = (String)map.get("payType");
                // 获取支付价格
                Float payPrice = Float.valueOf((String)map.get("payPrice"));
                // 设置支付状态
                Integer orderStatus = 0;
                // 创建订单实体
                Orders orders = new Orders();
                orders.setOrdersId(orderId.toString());
                Account account = new Account();
                account.setAccountId(accountId);
                orders.setAccount(account);
                Screening screening = new Screening();
                screening.setScreeningId(screeningId);
                orders.setScreening(screening);
                orders.setOrdersTime(newDate);
                orders.setPayType(payType);
                orders.setPayPrice(payPrice);
                orders.setOrdersStatus(orderStatus);
                // 插入数据进数据库
                ordersMapper.insert(orders);

                // 单张票价
                Float onePrice = payPrice/seatArray.length;
                for (String s : seatArray) {
                    // 创建订单详情表记录
                    Integer seat = Integer.valueOf(s);
                    int line = seat/SEAT_COLUMN+1;
                    int column = seat%SEAT_COLUMN+1;
                    OrdersDetail ordersDetail = new OrdersDetail();
                    ordersDetail.setOrders(orders);
                    ordersDetail.setSeatLine(line);
                    ordersDetail.setSeatColumn(column);
                    ordersDetail.setOrdersDetailPrice(onePrice);
                    ordersDetailMapper.insert(ordersDetail);
                }


            }catch (Exception e){
                LOGGER.debug(e.getMessage());
                // 设置回滚
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return false;

            }

        }
        return true;
    }

    @Override
    public boolean paySuccess(String orderId) {
        // 更新订单状态
        try{
            ordersMapper.updateStatus(orderId, 1);
        }catch(Exception e){
            e.printStackTrace();
            return false;
        }
        return true;
    }

    @Override
    public PageInfo<Orders> getUserOrders(Map<String, String> condition) {
        // 获取页码
        String num = condition.get("pageNum");
        if (num == null){
            num = "1";
        }
        Integer pageNum = Integer.valueOf(num);
        // 获取显示数量
        String size = condition.get("pageSize");
        if (size == null){
            size = "10";
        }
        Integer pageSize = Integer.valueOf(size);
        PageHelper.startPage(pageNum,pageSize);
        List<Orders> ordersList = ordersMapper.getOrdersList(condition);
        PageInfo<Orders> pageInfo = new PageInfo<Orders>(ordersList);
        return pageInfo;
    }

    @Override
    public boolean createRefund(Map<String, String> map) {

        // 获取订单号
        String ordersId = map.get("ordersId");
        // 根据订单号查询是否已经存在退单申请
        Refund refundByOrdersId = refundMapper.getRefundByOrdersId(ordersId);
        if(refundByOrdersId != null){
            return false;
        }
        // 获取退单编号
        String refundId = "back"+System.currentTimeMillis()+(new Random().nextInt(8999)+1000);
        // 获取退单申请内容（非必填）
        String refundContent = map.get("refundContent");
        // 退单状态
        Integer refundStatus = 0;
        // 退单时间
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String refundTime = formatter.format(now);
        // 退单金额
        Float refundPrice = 0.0f;
        // 1. 由订单号获取时间
        Orders oneOrder = ordersMapper.getOneOrder(ordersId);
        String ordersTime = oneOrder.getOrdersTime();
        // 2.获取场次开始时间
        Integer screeningId = oneOrder.getScreening().getScreeningId();
        Screening screening = screeningMapper.getScreeningById(screeningId);
        String screeningStartTime = screening.getScreeningStartTime();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            long oTime = sdf.parse(ordersTime).getTime();
            long sTime = sdf.parse(screeningStartTime).getTime();
            if(sTime-oTime<1000*60*30){ // 如果低于30分钟，不予退回
                return false;
            }else if(sTime-oTime < 1000*60*60*2){ // 如果低于低于2小时，退50%
                refundPrice = oneOrder.getPayPrice()*0.5f;
            }else if(sTime-oTime < 1000*60*60*24) { // 如果在24小时内，退80%
                refundPrice = oneOrder.getPayPrice()*0.8f;
            }else{
                refundPrice = oneOrder.getPayPrice()*0.9f;
            }

        } catch (ParseException e) {
            e.printStackTrace();
            return false;
        }

        // 创建记录
        Refund refund = new Refund();
        refund.setRefundId(refundId);
        refund.setOrders(oneOrder);
        refund.setRefundContent(refundContent);
        refund.setRefundPrice(refundPrice);
        refund.setRefundStatus(refundStatus);
        refund.setRefundTime(refundTime);

        refundMapper.insert(refund);


        return true;
    }

    @Override
    public boolean deleteRefund(String refundId) {
        return refundMapper.delete(refundId)>0;
    }


}
